use crate::{extract_field_ids, extract_record_ids, JwtClaims, WebResponseSupportTrait};
use salvo::prelude::JwtAuthDepotExt;
use salvo::{handler, Depot, Request, Response};
use serde_json::Value;
use std::collections::HashMap;
use visit_dd_core::field::VddField;
use visit_dd_core::i18n_text::{E_ARG_BAD, E_NO_PERMISSION_FOR_ACTION};
use visit_dd_core::proj::VddMessage;
use visit_dd_core::query::WebQueryParams;
use visit_dd_core::record::{RecordSubscriber, VddRecord};
use visit_dd_core::{i18n, Astr, RecordId, UserId};
use visit_dd_db::query_db::page;
use visit_dd_db::record_db::RecordDbTrait;
use visit_dd_db::sqlx::SqlxDataStoreTrait;
use visit_dd_db::{cache, model_db, record_rule_db, record_version_db, subscribe};
use visit_dd_db::{message_db, query_db, record_db, visit_db};

/// 关系型数据库的记录数统计
#[handler]
pub(crate) async fn g_count_record(_req: &mut Request, depot: &mut Depot, res: &mut Response) {
    let jwt = &depot.jwt_auth_data::<JwtClaims>().unwrap().claims;
    let model_ids = model_db::m_select_ids_by_uid(&jwt.uid).await;
    let mut count_map = HashMap::<u64, usize>::new();
    for model_id in model_ids {
        let model = model_db::m_load(model_id).await;
        match model.store.clone() {
            None => {
                let record_count = record_db::count_in_model(model_id);
                count_map.insert(model_id, record_count);
            }
            Some(ds_cfg) => {
                if ds_cfg.test_connection().await {
                    let record_count = ds_cfg.count_records(model_id).await.unwrap();
                    count_map.insert(model_id, record_count);
                } else {
                    let _ = message_db::send(&VddMessage::new(
                        &UserId(0),
                        &jwt.uid,
                        &i18n!(1357, &model.name),
                    ));
                }
            }
        }
    }
    res.ok(&count_map);
}

/// 保存一条记录，只允许作者访问
#[handler]
pub(crate) async fn p_save_record(req: &mut Request, depot: &mut Depot, res: &mut Response) {
    let jwt: &JwtClaims = &depot.jwt_auth_data::<JwtClaims>().unwrap().claims;
    let j: Value = req.parse_body::<Value>().await.expect(&i18n!(E_ARG_BAD));
    let model_id = j["modelId"].as_u64().expect(&i18n!(E_ARG_BAD));
    let s = cache::get_schema(model_id).await.unwrap();
    let old_to_version = j["oldToVersion"].as_bool().unwrap_or(false);
    let mut record: VddRecord;
    let mut is_update = false;
    match j["oldKey"].as_u64() {
        Some(old_key) => {
            is_update = true;
            let old_record = record_db::load_record(&s, &RecordId(old_key), &[]);
            match old_record {
                None => {
                    res.error(&i18n!(1123, &old_key.to_string()));
                    return;
                }
                Some(rec_o) => {
                    record = rec_o;
                    if !s.model.belong_to(&jwt.uid) && !record.belong_to(&jwt.uid) {
                        res.error("不是模型作者或记录贡献者，无权进行操作");
                        return;
                    }
                }
            }
        }
        None => {
            record = VddRecord::new_default(jwt.uid.clone(), model_id);
        }
    }
    let field_map = VddField::v_to_m(&s.fields);
    record.update_form_json(&j, &field_map, &jwt.uid);
    // 检查记录填写是否符合字段设定的要求
    let result = record.fit_field_defines(&s, is_update);
    if result.is_err() {
        res.error(&result.unwrap_err());
        return;
    }
    // 模型自身的值规则限制
    let mut rrs = record_rule_db::rr_select_in_model(model_id).await;
    // 供模型消费的其他生产者模型的关于本模型的消费规则
    let rrs2 = record_rule_db::rr_select_consume_by_model(model_id).await;
    rrs2.iter().for_each(|rr| {
        rrs.push(rr.clone());
    });
    let result = record.fit_record_rules(&s, &rrs, is_update).await;
    if result.is_err() {
        res.error(&result.unwrap_err());
        return;
    }
    let r = record_db::save(&mut record, &s, &rrs, old_to_version).await;
    res.wrap(r);
}

#[handler]
pub(crate) async fn p_share_save(req: &mut Request, depot: &mut Depot, res: &mut Response) {
    let jwt: &JwtClaims = &depot.jwt_auth_data::<JwtClaims>().unwrap().claims;
    let j: Value = req
        .parse_body::<Value>()
        .await
        .expect(i18n!(E_ARG_BAD).as_ref());
    let model_id = j["modelId"].as_u64();
    if model_id.is_none() {
        res.error(i18n!(E_ARG_BAD).as_ref());
        return;
    }
    let model_id = model_id.unwrap();
    let s = cache::get_schema(model_id).await.unwrap();
    let vg = visit_db::vg_try_load_in_model_by_user(model_id, &jwt.uid).await;
    if let Some(vg) = vg.clone() {
        if !vg.write_able {
            res.error("未获得模型的写入权限");
            return;
        }
    } else {
        res.error(i18n!(1101).as_ref());
        return;
    }
    let vg = vg.unwrap();
    let mut is_update = false;
    let mut record: VddRecord;
    let field_map = VddField::v_to_m(&s.fields);
    if j["oldKey"].is_u64() {
        is_update = true;
        let record_opt = record_db::load_record(
            &s,
            &RecordId(j["oldKey"].as_u64().expect(i18n!(E_ARG_BAD).as_ref())),
            &[],
        );
        if record_opt.is_none() {
            res.error("加载旧记录失败");
            return;
        } else {
            record = record_opt.unwrap();
            match record.fit_vg(&vg, &s.model.uid, &jwt.uid) {
                Err(e) => {
                    res.error(&e.to_string());
                    return;
                }
                Ok(v) => {
                    if !v.0 {
                        res.error("无权维护旧记录");
                        return;
                    }
                }
            }
        }
    } else {
        record = VddRecord::new_default(jwt.uid.clone(), model_id);
    }
    let mut old_fv_map = HashMap::new();
    if !is_update {
        record.update_form_json(&j, &field_map, &jwt.uid);
    } else {
        old_fv_map = record.update_form_json_with_vg(&j, &field_map, &vg, &jwt.uid);
    }
    // 检查此授权的可写性
    let check_result = record.change_by_vg_for_write(&vg, is_update, old_fv_map);
    if check_result.is_err() {
        res.error(&check_result.unwrap_err());
        return;
    }
    //
    let check_result = record.fit_field_defines(&s, is_update);
    if check_result.is_err() {
        res.error(&check_result.unwrap_err());
        return;
    }
    //
    let u_rules = record_rule_db::rr_select_in_model(model_id).await;
    let check_result = record.fit_record_rules(&s, &u_rules, is_update).await;
    if check_result.is_err() {
        res.error(&check_result.unwrap_err());
        return;
    }
    let r = record_db::visit_save(&mut record, &s, &u_rules, &vg, is_update).await;
    res.wrap(r);
}

#[handler]
pub(crate) async fn p_page(req: &mut Request, _depot: &mut Depot, res: &mut Response) {
    let j: Value = req
        .parse_body::<Value>()
        .await
        .expect(i18n!(E_ARG_BAD).as_ref());
    let query_params = WebQueryParams::try_from(&j).unwrap();
    let schema = cache::get_schema(query_params.model_id.expect(i18n!(E_ARG_BAD).as_ref()))
        .await
        .unwrap();
    // 开始读取数据
    match schema.model.store.clone() {
        None => {
            res.ok(&page(&query_params).await);
        }
        Some(ds_cfg) => {
            if !ds_cfg.test_connection().await {
                res.error(i18n!(1201).as_ref());
                return;
            }
            res.ok(&ds_cfg.sqlx_get_page(&query_params, &schema).await);
        }
    }
}

#[handler]
pub(crate) async fn p_share_page(req: &mut Request, depot: &mut Depot, res: &mut Response) {
    let jwt = &depot.jwt_auth_data::<JwtClaims>().unwrap().claims;
    let j: Value = req
        .parse_body::<Value>()
        .await
        .expect(i18n!(E_ARG_BAD).as_ref());
    let sqp = query_db::sqp_from_json(&j, &jwt.uid).await;
    if sqp.is_err() {
        res.error(&sqp.unwrap_err());
        return;
    }
    let sqp = sqp.unwrap();
    // 开始读取数据
    if sqp.schema.model.store.is_some() {
        let ds_cfg = sqp.schema.model.store.to_owned().unwrap();
        if !ds_cfg.test_connection().await {
            res.error(i18n!(1201).as_ref());
            return;
        }
        res.ok(&ds_cfg.sqlx_share_page(&sqp).await);
    } else {
        res.ok(&query_db::share_page(&sqp).await);
    };
}

#[handler]
pub(crate) async fn p_remove_record(req: &mut Request, depot: &mut Depot, res: &mut Response) {
    let jwt: &JwtClaims = &depot.jwt_auth_data::<JwtClaims>().unwrap().claims;
    let j: Value = req.parse_body::<Value>().await.unwrap();
    let record_ids = j["recordIds"].as_array();
    match record_ids {
        None => res.error(i18n!(E_ARG_BAD).as_ref()),
        Some(record_ids) => {
            let rids = record_ids
                .iter()
                .map(|x| x.as_u64())
                .filter(|x| x.is_some())
                .map(|x| RecordId(x.unwrap()))
                .collect::<Vec<RecordId>>();
            let model_id = j["modelId"].as_u64().unwrap();
            let s = cache::get_schema(model_id).await.unwrap();
            let r = record_db::delete_some(&rids, &s, &jwt.uid).await;
            res.wrap(r);
        }
    }
}

/// 获取一条记录的版本数量
#[handler]
pub(crate) async fn g_version_count(req: &mut Request, _depot: &mut Depot, res: &mut Response) {
    let record_id = req.param::<u64>("record-id").unwrap();
    let count = record_version_db::count_version(&RecordId(record_id));
    res.ok(&count);
}

async fn _check_version_action_right(
    record_id: &RecordId,
    requester_id: &UserId,
) -> Result<u64, Astr> {
    let record_meta = record_db::load_meta_from_rdb(&record_id);
    if let Some(record_meta) = record_meta {
        let model = model_db::m_load(record_meta.model_id).await;
        if record_meta.uid != requester_id.clone() && model.uid != record_meta.uid {
            Err("非记录作者或模型作者无权进行此操作".into())
        } else {
            Ok(model.id)
        }
    } else {
        Err("Record not found".into())
    }
}

/// 获取一条记录的版本列表
#[handler]
pub(crate) async fn g_versions(req: &mut Request, depot: &mut Depot, res: &mut Response) {
    let jwt: &JwtClaims = &depot.jwt_auth_data::<JwtClaims>().unwrap().claims;
    let record_id = req.param::<u64>("record-id").unwrap();
    let record_id = RecordId(record_id);
    let check_result = _check_version_action_right(&record_id, &jwt.uid).await;
    if check_result.is_err() {
        res.error(&check_result.unwrap_err());
    } else {
        res.ok(&record_version_db::select_versions(&record_id));
    }
}

#[handler]
pub(crate) async fn p_remove_version(req: &mut Request, depot: &mut Depot, res: &mut Response) {
    let jwt: &JwtClaims = &depot.jwt_auth_data::<JwtClaims>().unwrap().claims;
    let j: Value = req.parse_body::<Value>().await.unwrap();
    let record_id = j["recordId"].as_u64().unwrap();
    let record_id = RecordId(record_id);
    let check_result = _check_version_action_right(&record_id, &jwt.uid).await;
    if check_result.is_err() {
        res.error(&check_result.unwrap_err());
    } else {
        let version_id = j["versionId"].as_u64().unwrap();
        let ares = record_version_db::delete_version(&record_id, version_id);
        res.wrap(ares);
    }
}

/// 回滚某个版本的记录
#[handler]
pub(crate) async fn p_restore_version(req: &mut Request, depot: &mut Depot, res: &mut Response) {
    let jwt: &JwtClaims = &depot.jwt_auth_data::<JwtClaims>().unwrap().claims;
    let j: Value = req.parse_body::<Value>().await.unwrap();
    let record_id = j["recordId"].as_u64().expect(i18n!(E_ARG_BAD).as_ref());
    let record_id = RecordId(record_id);
    let version_id = j["versionId"].as_u64().expect(i18n!(E_ARG_BAD).as_ref());
    let check_result = _check_version_action_right(&record_id, &jwt.uid).await;
    if check_result.is_err() {
        res.error(&check_result.unwrap_err());
    } else {
        let model_id = check_result.unwrap();
        let ares = record_version_db::roll_back(model_id, &record_id, version_id).await;
        res.wrap(ares);
    }
}

/// 用户订阅数据更新
#[handler]
pub(crate) async fn p_subscribe_record_change(
    req: &mut Request,
    depot: &mut Depot,
    res: &mut Response,
) {
    let jwt: &JwtClaims = &depot.jwt_auth_data::<JwtClaims>().unwrap().claims;
    let model_id = req.param::<u64>("model-id").unwrap();
    let model = model_db::m_load(model_id).await;
    if model.store.is_some() {
        res.error("非本地存储数据的模型不能订阅更新");
        return;
    }
    if subscribe::sc_load(model_id, &jwt.uid).await.is_ok() {
        res.error("已定阅，无需重复操作");
    } else {
        let r_sub = RecordSubscriber::new(model_id, jwt.uid.clone());
        let r = subscribe::sc_save(&r_sub).await;
        res.wrap(r);
    }
}

/// 用户取消订阅数据更新
#[handler]
pub(crate) async fn p_cancel_subscribe(req: &mut Request, depot: &mut Depot, res: &mut Response) {
    let jwt: &JwtClaims = &depot.jwt_auth_data::<JwtClaims>().unwrap().claims;
    let model_id = req.param::<u64>("model-id").unwrap();
    let r = subscribe::sc_delete(model_id, &jwt.uid).await;
    res.wrap(r);
}

/// 用户重置数据更新 清空所有已有的数据更新记录，从空状态开始接收数据更新
#[handler]
pub(crate) async fn p_reset_subscription(req: &mut Request, depot: &mut Depot, res: &mut Response) {
    let jwt: &JwtClaims = &depot.jwt_auth_data::<JwtClaims>().unwrap().claims;
    let model_id = req.param::<u64>("model-id").unwrap();
    let ares = subscribe::reset_subscription(model_id, &jwt.uid).await;
    res.wrap(ares);
}

/// 用户分页查看数据更新
#[handler]
pub(crate) async fn p_subscription_page(req: &mut Request, depot: &mut Depot, res: &mut Response) {
    let jwt: &JwtClaims = &depot.jwt_auth_data::<JwtClaims>().unwrap().claims;
    let j: Value = req
        .parse_body::<Value>()
        .await
        .expect(i18n!(E_ARG_BAD).as_ref());
    let sqp = query_db::sqp_from_json(&j, &jwt.uid).await;
    if sqp.is_err() {
        res.error(&sqp.unwrap_err());
        return;
    }
    let sqp = sqp.unwrap();
    // 开始读取数据
    if sqp.schema.model.store.is_some() {
        res.error("代理访问模型不支持新数据订阅");
    } else {
        let data_page = query_db::subscribe_get_page(&sqp).await;
        res.ok(&data_page);
    }
}

/// 获取更新内容概览
#[handler]
pub(crate) async fn g_subscription_overview(
    req: &mut Request,
    depot: &mut Depot,
    res: &mut Response,
) {
    let jwt: &JwtClaims = &depot.jwt_auth_data::<JwtClaims>().unwrap().claims;
    let model_id = req.param::<u64>("model-id").unwrap();
    let r_sub = subscribe::sc_load(model_id, &jwt.uid).await;
    if r_sub.is_err() {
        res.error(&r_sub.unwrap_err());
        return;
    }
    let r_sub = r_sub.unwrap();
    res.ok(&subscribe::overview_subscription(&r_sub).unwrap());
}

/// 获取回收站的内容树
#[handler]
pub(crate) async fn g_trash_tree(_req: &mut Request, depot: &mut Depot, res: &mut Response) {
    let jwt: &JwtClaims = &depot.jwt_auth_data::<JwtClaims>().unwrap().claims;
    let tree = model_db::tree_of_trash(jwt.uid.clone()).await;
    res.ok(&tree);
}

///
#[handler]
pub(crate) async fn g_records_in_trash(req: &mut Request, _depot: &mut Depot, res: &mut Response) {
    let j = req
        .parse_body::<Value>()
        .await
        .expect(i18n!(E_ARG_BAD).as_ref());
    let field_ids = extract_field_ids(&j);
    let q = WebQueryParams::try_from(&j).unwrap();
    let records = record_db::select_in_trash(&field_ids, &q);
    res.ok(&records);
}

///
#[handler]
pub(crate) async fn p_drop_from_trash(req: &mut Request, _depot: &mut Depot, res: &mut Response) {
    let j = req
        .parse_body::<Value>()
        .await
        .expect(i18n!(E_ARG_BAD).as_ref());
    let record_ids = extract_record_ids(&j);
    let ares = record_db::drop_from_trash(&record_ids);
    res.wrap(ares);
}

///
#[handler]
pub(crate) async fn p_restore(req: &mut Request, _depot: &mut Depot, res: &mut Response) {
    let j = req
        .parse_body::<Value>()
        .await
        .expect(i18n!(E_ARG_BAD).as_ref());
    let record_ids = extract_record_ids(&j);
    let field_ids = extract_field_ids(&j);
    let model_id = j["modelId"].as_u64().expect(i18n!(E_ARG_BAD).as_ref());
    let ares = record_db::restore(model_id, &field_ids, &record_ids).await;
    res.wrap(ares);
}

/// 加载一条记录 用于从记录详情中加载嵌入的关联记录信息
#[handler]
pub(crate) async fn g_record(req: &mut Request, depot: &mut Depot, res: &mut Response) {
    let jwt: &JwtClaims = &depot.jwt_auth_data::<JwtClaims>().unwrap().claims;
    let model_id = req.param::<u64>("model-id").unwrap();
    let schema_ref = cache::get_schema(model_id).await.unwrap();
    if schema_ref.model.uid != jwt.uid {
        // 非模型作者，校验权限
        let vg = visit_db::vg_try_load_in_model_by_user(model_id, &jwt.uid).await;
        if vg.is_none() {
            res.error(i18n!(E_NO_PERMISSION_FOR_ACTION).as_ref());
            return;
        }
    }
    let record_id = req.param::<u64>("record-id").unwrap();
    let record_id = RecordId(record_id);
    let r = record_db::load_record(&schema_ref, &record_id, &[]);
    if let Some(record) = r {
        let rdd = record.new_display(&schema_ref).await;
        res.ok(&rdd);
    } else {
        res.error("记录未找到");
    }
}
